package com.star.system.config;

import cn.hutool.core.util.StrUtil;
import com.star.security.exception.UsernameNotFoundException;
import com.star.security.user.Users;
import com.star.security.user.UserDetails;
import com.star.security.user.UserDetailsService;
import com.star.system.entity.User;
import com.star.system.entity.UserRole;
import com.star.system.enums.DefaultUser;
import com.star.system.enums.UserType;
import com.star.system.mapper.RoleMapper;
import com.star.system.mapper.UserMapper;
import com.star.system.mapper.UserRoleMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取登录用户信息
 *
 * @author yangzj
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    @Override
    public UserDetails getByUsername(String username, Object details) throws UsernameNotFoundException {
        Integer type = Optional.ofNullable(details).map(c -> Integer.parseInt(c.toString())).orElse(null);
        Users user = userMapper.getByUsername(username, type);
        if (user == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        return this.buildUser(user);
    }

    @Override
    public UserDetails getByOpenId(String openId, String unionId, Object details) throws UsernameNotFoundException {
        Users user = userMapper.getByOpenId(openId);
        if(user == null) {
            Integer type = Integer.parseInt(details.toString());
            user = this.register(openId, unionId, type);
        }
        return this.buildUser(user);
    }

    /**
     * 注册微信小程序用户
     *
     * @param openId  openId
     * @param unionId unionId
     * @param type    类型
     * @return {@link Users}
     */
    private Users register(String openId, String unionId, Integer type) {
        Long defaultUserId = DefaultUser.SUPER_ADMIN.getId();
        User user = new User().setUsername(openId).setOpenId(openId).setUnionId(unionId)
                .setType(type)
                .setEnabled(true)
                .setCreator(defaultUserId).setUpdater(defaultUserId);
        userMapper.insert(user);
        DefaultUser defaultUser = DefaultUser.getByUserType(type);
        UserRole userRole = new UserRole().setUserId(user.getId())
                .setRoleId(defaultUser.getRoleId())
                .setCreator(defaultUserId);
        userRoleMapper.insert(userRole);
        return new Users().setId(user.getId())
                .setUsername(openId).setOpenId(openId)
                .setRoles(Collections.singleton(defaultUser.getRoleCode()))
                .setSuperAdmin(false).setEnabled(true);
    }


    /**
     * 构建用户
     *
     * @param user 使用者
     * @return {@link Users}
     */
    private Users buildUser(Users user) {
        Long userId = user.getId();
        Set<String> roleCodes = roleMapper.getRoles(userId);
        boolean superAdmin = roleCodes.contains(DefaultUser.SUPER_ADMIN.getRoleCode());
        return user.setRoles(roleCodes)
                .setSuperAdmin(superAdmin)
                .setAuthorities(this.splitAuthorities(user.isSuperAdmin() ? new HashSet<>() : roleMapper.getAuthorities(userId)));
    }

    /**
     * 处理权限标识 逗号隔开转集合
     *
     * @param authorities 权限标识
     * @return {@link Set}<{@link String}>
     */
    private Set<String> splitAuthorities(Set<String> authorities) {
        return authorities.stream()
                .map(c -> StrUtil.split(c, ","))
                .flatMap(Collection::stream).collect(Collectors.toSet());
    }
}
